/*
 * enc_netipaddr.cpp
 *
 *  Created on: 2018年11月6日
 *  Author: Degang.Wu (windragon@126.com)
 *  Desc:
 */

#include "public.h"
#include "enc_gpio.h"
#include "hi_memmap.h"

static char  	g_master_ipaddr[64];
static char		g_slave_ipaddrs[ENC_MAX_SUB_BOARD][64];
static const char* g_netmask = "255.255.255.0";

int hienc_set_mstip(const char* ipaddr)
{
	struct in_addr addr;
	if ( 0 == inet_aton(ipaddr, &addr))
	{
		return -1;
	}
	snprintf(g_master_ipaddr, sizeof(g_master_ipaddr), "%s", ipaddr);

	return 0;
}

//设置第一个子板的IP，后面的子板递加
int hienc_set_slv0ip(const char* ipaddr)
{
	struct in_addr addr;
	if ( 0 == inet_aton(ipaddr, &addr))
	{
		return -1;
	}

	addr.s_addr = ntohl(addr.s_addr);
	for (int i = 0; i < ENC_MAX_SUB_BOARD; i++)
	{
		struct in_addr dst_addr;
		dst_addr.s_addr = htonl(addr.s_addr);
//		printf("0x%x\n", addr.s_addr);
		const char* dst = inet_ntoa(dst_addr);
//		printf("%s\n", dst);
		snprintf(g_slave_ipaddrs[i], sizeof(g_slave_ipaddrs[i]), "%s", dst);
		addr.s_addr++;
	}

	return 0;
}

const char* hienc_get_priv_slv_ipaddr(int subidx)
{
	if (subidx < 0 || subidx >= ENC_MAX_SUB_BOARD)
	{
		return NULL;
	}

	return g_slave_ipaddrs[subidx];
}

const char* hienc_get_priv_mst_ipaddr()
{
	return g_master_ipaddr;
}

const char* hienc_get_priv_netmask()
{
	return g_netmask;
}

U16 hienc_get_priv_mst_port()
{
	return ENC_MASTER_PORT;
}

U16 hienc_get_priv_slv_port()
{
	return ENC_SLAVE_PORT;
}

//获取子板ID号 ： 0-5
int hienc_get_subidx()
{
	U32 idx = 0;
#ifdef __RELEASE_HIENC
	void* pMem = memmap(GPIO_REG_ADDR_SUBID, DEFAULT_MD_LEN);
	 idx = *(U32*)pMem;
	 memunmap(pMem);

//	if (hienc_gpio_export(SYSFS_GPIO_SUBID_PIN) < 0)
//	{
//		return 0;
//	}
//
//	int idx = hienc_gpio_read(SYSFS_GPIO_SUBID_PIN);
//	if (idx < 0)
//	{
//		return 0;
//	}
//	else
//	{
//		return idx & 0x7; 	//低3位
//	}
#endif

	return idx;
}

void hienc_init_network()
{
	const char* ipaddr = NULL;
	const char* ethname = NULL;
	const char* role = NULL;
	if (enc_is_master())
	{
		role = "MASTER";
		ipaddr = hienc_get_priv_mst_ipaddr();
		if (g_encset_mst)
		{
			ethname = (const char*)(g_encset_mst->enc_ethdevname[ENC_ETHID_PRIV]);
		}
	}
	else
	{
		role = "SLAVE";
		ipaddr = hienc_get_priv_slv_ipaddr(hienc_get_subidx());
		if (g_encset_slv)
		{
			//ethname = (const char*)(g_encset_slv->enc_ethdevname[ENC_ETHID_PRIV]);
			ethname = (const char*)(g_encset_slv->enc_ethdevname[0]);
		}
	}

	if (NULL == ipaddr || NULL == ethname)
	{
		BW_INFO("INIT(%s) network error, ip=%s, ethname=%s\n", role, ipaddr, ethname);
		return;
	}

	char cmd[SZ_1K];
	snprintf(cmd, sizeof(cmd), "ifconfig %s %s netmask %s", ethname, ipaddr, hienc_get_priv_netmask());
	BW_INFO("%s init network:%s\n", role, cmd);

#ifdef __RELEASE_HIENC
	system(cmd);
#endif
}


/*
 * 从接口上获取ip地址
 * 成功返回0， 失败返回-1
 */
int hienc_net_get_if_ipaddr(const char* ethname, char* buf, int buflen)
{
	int sfd, if_count, i;
	struct ifconf ifc;
	struct ifreq ifr[10];
	char ipaddr[INET_ADDRSTRLEN] = { '\0' };
	int ret = -1;

	if (!buf)
	{
		return -1;
	}

	memset(buf, 0, buflen);

	memset(&ifc, 0, sizeof(struct ifconf));

	sfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sfd < 0)
	{
		return -1;
	}

	ifc.ifc_len = 10 * sizeof(struct ifreq);
	ifc.ifc_buf = (char *) ifr;

	ioctl(sfd, SIOCGIFCONF, (char *) &ifc);

	if_count = ifc.ifc_len / (sizeof(struct ifreq));
	for (i = 0; i < if_count; i++)
	{
		if (0 == strcmp(ifr[i].ifr_name, "lo"))
		{
			continue;
		}
		if (0 == strcmp(ifr[i].ifr_name, ethname))
		{
			inet_ntop(AF_INET,
					&(((struct sockaddr_in *) &(ifr[i].ifr_addr))->sin_addr),
					ipaddr, INET_ADDRSTRLEN);
			snprintf(buf, buflen, "%s", ipaddr);
			ret = 0;
			break;
		}
	}

	close(sfd);

	return ret;
}
